package com.ma.table;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
//import com.badlogic.gdx.graphics.g2d.stbtt.TrueTypeFontFactory;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.scenes.scene2d.actions.MoveToAction;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.TimeUtils;
import com.ma.gestureDetectors.MisilGestureDetector;
import com.ma.gestureDetectors.Botones.BotonDoblarGestureDetector;
import com.ma.gestureDetectors.Botones.BotonVidaGestureDetector;
import com.ma.logica.Assets;
import com.ma.logica.Constantes;
import com.ma.logica.LogicaJuego;
import com.ma.logica.Sonido;
import com.ma.logica.Spawns;
import com.ma.screens.ScreenOne;
import com.ma.table.actors.Asteroide;
import com.ma.table.actors.Background;
import com.ma.table.actors.Coin;
import com.ma.table.actors.Misil;
import com.ma.table.actors.botones.BotonDoblar;
import com.ma.table.actors.botones.BotonVida;

public class LogicaScreenOne extends Table {

	public static final float WORLD_WIDTH = 12.5f;
	public static final float WORLD_HEIGHT = 7.5f;
	public static final float FONT_SIZE = 0.5f;


	
	private LogicaJuego logicaJuego;
	private Background bg;
	private BotonDoblar botonDoblar;
	private BotonVida botonVida;
	private Asteroide primerAsteroide;
	public Misil misil;
	public MoveToAction moverMisil;

	private long timeAsteroides;
	public long timeAumentoAsteroides = 2000;
	private int asteroidesDestruidos = 0, numMisiles = 0,
			incrementoMonedas = 1, multiplicadorIncrementoMonedas = 1;

	public boolean start = false, resultado = false, misilIniciado = true;

	private int vidas = 1;

	BitmapFont font, font1;
	CharSequence str = "Asteroides destruidos: ";

	private Spawns spawns;
	public Array<Asteroide> asteroides;
	public Array<Coin> coins;
	
	/////////////FUENTE///////////////////
	public static final String FONT_CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890][_!$%#@|\\/?-+=()*&.;,{}\"´`'<>";
	//////////////////////////////////////

	public LogicaScreenOne(final LogicaJuego logicaJuego, ScreenOne scOne) {
		this.logicaJuego = logicaJuego;
		this.spawns = new Spawns(this);
		
		// El metodo setbounds coloca un Rectangulo (X,Y,Width,Height)
		setBounds(0, 0, LogicaJuego.w, LogicaJuego.h);
		setClip(true);

		asteroides = new Array<Asteroide>();
		coins = new Array<Coin>();
		
		// Instanciar Actores
		bg = new Background();
		botonDoblar = new BotonDoblar();
		botonDoblar.addListener(new BotonDoblarGestureDetector(this,logicaJuego));
		botonVida = new BotonVida(botonDoblar);
		botonVida.addListener(new BotonVidaGestureDetector(this,logicaJuego));
		
		
		primerAsteroide = iniciarPrimerAsteroide();
		primerAsteroide.addListener(new InputListener(){
			 	public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
			 		prepararStart();
			 		return false;
			 	}
		});
		
		bg.addListener(new InputListener(){
			public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
				if(resultado){
					Gdx.app.exit();
				}
				return false;
			}
		});
		
//		this.moverMisil = new MoveToAction();
//		this.moverMisil.setDuration(1);
//		this.misil = new Misil();
//		this.misil.setPosition(3,0.5f*Gdx.graphics.getPpcY());
//		this.misil.addListener(new MisilGestureDetector(this));
		// Añadiendo Actores
		addActor(bg);
		addActor(botonDoblar);
		addActor(botonVida);
		addActor(primerAsteroide);
		iniciarMisil();
		

		Sonido.musicaPlay();
		
		timeAsteroides = TimeUtils.millis();
		font = new BitmapFont();
		font1 = new BitmapFont();
		
//		/////////////////FUENTE/////////////////////////
//		font = TrueTypeFontFactory.createBitmapFont(
//				Gdx.files.internal(Constantes.NOMBRE_FUENTE), FONT_CHARACTERS,
//				WORLD_WIDTH, WORLD_HEIGHT, FONT_SIZE, LogicaJuego.w, LogicaJuego.h);
		font.setColor(1f, 0f, 0f, 1f); //Color Rojo

	}

	// Metodo act se ejecuta al igual que el render, es donde insertaremos la
	// lógica.
	@Override
	public void act(float delta) {
		if(start){
		super.act(delta);

			// Comprobar si hay que crear una nueva moneda
			if (TimeUtils.millis() - timeAsteroides > timeAumentoAsteroides) {
				asteroides = spawns.spawnAsteroide(asteroides);
				timeAsteroides = TimeUtils.millis();
			}
	
			// Reducir tiempo de crear un asteroide
			if (asteroidesDestruidos % 2 == 0 && asteroidesDestruidos != 0) {
				timeAumentoAsteroides -= timeAumentoAsteroides * 0.05;
				asteroidesDestruidos = 0;
			}
	
			// misil
	//		if (asteroidesDestruidosMarcador % 100 == 0
	//				&& asteroidesDestruidosMarcador != 0) {
	//			misil = true;
	//		}
		}
	}

	// Método Draw contiene el SpriteBatch para dibujar.
	@Override
	public void draw(Batch batch, float parentAlpha) {
		
		super.draw(batch, parentAlpha);
		batch.setColor(Color.WHITE);

		font.draw(batch, str + " " + logicaJuego.getAsteroidesDestruidosMarcador(), 12,LogicaJuego.h - 12);
		font.draw(batch, "Monedas: "+logicaJuego.getMonedas(), 12,LogicaJuego.h - 48);
		font.draw(batch, "Record Asteroides Destruidos: "+logicaJuego.getMaxAsteroidesDestruidos()+" Misiles: "+numMisiles, 12,LogicaJuego.h - 108);
		batch.draw(Assets.instance.images.coinTexture, Constantes.POSICON_X_COIN, Constantes.POSICON_Y_COIN, Constantes.TAMANIO_COIN_H, Constantes.TAMANIO_COIN_W);
		
		if(start){
			// Iteracion Asteroides
			for(Asteroide ast: asteroides){
				if(ast.getHits()==0){
					int tmp = multiplicadorIncrementoMonedas;
					if(ast.isMultiHit()){
						multiplicadorIncrementoMonedas = multiplicadorIncrementoMonedas*3;
					}
					asteroideDestruido(asteroides.indexOf(ast, false), ast);
					multiplicadorIncrementoMonedas = tmp;
				}else if (ast.getY() + ast.getHeight() < 0 && ast.getHits()>0) {
					if(asteroides.removeValue(ast, false)){
						this.removeActor(ast);
					}
					vidas--;
					if(vidas == 0){
						finJuego();
					}else{
						timeAumentoAsteroides += timeAumentoAsteroides * 0.53;
						asteroides.clear();
						coins.clear();
						clearChildren();
						addActor(bg);
						iniciarMisil();
					}
				}else if(ast.getX() > LogicaJuego.w + (2*ast.getWidth()) || ast.getX() < 0 - (2*ast.getWidth())){
					if(asteroides.removeValue(ast, false)){
						this.removeActor(ast);
					}
				} else {				
					ast.setY(ast.getY() - ast.getVelocidad()* Gdx.graphics.getDeltaTime());
					if(ast.isMisil()){
						misil.clearActions();
			    		moverMisil.setPosition(ast.getX(), ast.getY());
			    		misil.addAction(moverMisil);
//			    		System.out.println("misil x: "+misil.getX()+" Ast X: "+ast.getX());
//			    		System.out.println("misil y: "+misil.getY()+" Ast y: "+ast.getY());
//			    		if(-3<(misil.getX()-ast.getX())&&(misil.getX()-ast.getX())<3 && -3<(misil.getX()-ast.getX())&&(misil.getY()-ast.getY())<3){ //Revisar esta condicion
			    		if(misil.getX()==ast.getX()){
			    			ast.destruido();
			    			ast.setHits(0);
			    			this.removeActor(misil);
			    			misil.remove();
			    			misilIniciado=true;
			    		}
					}
				}
			}
			
			// Iteracion Coins
			for(Coin coin: coins){
				if(Constantes.POSICON_X_COIN == coin.getX() && coin.getY() == Constantes.POSICON_Y_COIN){
					if(coin.getActions().size==0){
						logicaJuego.setMonedas(logicaJuego.getMonedas()+1);
					}
	    			Sonido.coinPlay();
					if(coins.removeValue(coin, false)){
						this.removeActor(coin);
					}
				}
			}
		}else if(resultado){
			font.draw(batch, logicaJuego.getAsteroidesDestruidosMarcador()+" Asteroides destruidos", LogicaJuego.w/4,LogicaJuego.h - 78);
		}else{
			font.draw(batch, "Destruye el Asteroide", primerAsteroide.getX(),primerAsteroide.getY()-20);
		}
	}
	
	
	public void asteroideDestruido(int index, Asteroide asteroide) {
		int incrementoTotal = incrementoMonedas*multiplicadorIncrementoMonedas;
		// Comprobar la duración de la explosion
		if (TimeUtils.millis() - asteroide.getTimeExplosion() > asteroide.getDuracionExplosion()) {
	    	asteroides.removeIndex(index);
	    	asteroide.remove();
	    	for(int i = 0; i<incrementoTotal; i++){
	    		spawns.spawnCoins(coins, asteroide);
	    	}
	    	asteroidesDestruidos++;
	    	logicaJuego.setAsteroidesDestruidosMarcador(logicaJuego.getAsteroidesDestruidosMarcador()+1);
			if(logicaJuego.getAsteroidesDestruidosMarcador()%10==0){
	    		incrementoMonedas++;
	    	}
		}
		if(asteroide.isMisil()&&numMisiles>0){
			iniciarMisil();
		}
	}
	
	private Asteroide iniciarPrimerAsteroide(){
		Asteroide asteroide = new Asteroide();
		asteroide.setMultiHit(false);
		asteroide.setHits(1);
		asteroide.setHeight(Constantes.TAMANIO_ASTEROIDE_H);
		asteroide.setWidth(Constantes.TAMANIO_ASTEROIDE_W);
		asteroide.setPosition(botonDoblar.getX(), botonDoblar.getY()-asteroide.getHeight());
		asteroides.add(asteroide);
		return asteroide;
	}
	
	public void prepararStart(){
		primerAsteroide.destruido();
 		primerAsteroide.setHits(0);
 		removeActor(botonDoblar);
 		removeActor(botonVida);
 		start=true;
	}
	
	private void finJuego(){
		logicaJuego.setMuerto(true);
		start = false;
		resultado = true;
		asteroides.clear();
		coins.clear();
		clearChildren();
		addActor(bg);
	}
	
	public void iniciarMisil(){
		if(misilIniciado){
			this.moverMisil = new MoveToAction();
			this.moverMisil.setDuration(1);
			this.misil = new Misil();
			this.misil.setPosition(3,0.5f*Gdx.graphics.getPpcY());
			this.misil.addListener(new MisilGestureDetector(this));
			this.addActor(misil);
			misilIniciado = false;
		}
		
	}
	
	public int getMultiplicadorIncrementoMonedas() {
		return multiplicadorIncrementoMonedas;
	}

	public void setMultiplicadorIncrementoMonedas(int multiplicadorIncrementoMonedas) {
		this.multiplicadorIncrementoMonedas = multiplicadorIncrementoMonedas;
	}
	
	public int getVidas() {
		return vidas;
	}

	public void setVidas(int vidas) {
		this.vidas = vidas;
	}
	
	public int getNumMisiles() {
		return numMisiles;
	}

	public void setNumMisiles(int numMisiles) {
		this.numMisiles = numMisiles;
	}
	
	public boolean isStart() {
		return start;
	}

	public void setStart(boolean start) {
		this.start = start;
	}
}
